#pragma once

#include "../Component.h"
#include "../GameObjects/Character.h"

#include <functional>
#include <vector>

class Vitality : public Component
{
public:
	Vitality();
	virtual ~Vitality();

	void update(unsigned int tick) override;

	void addBodypart(Character::BodyPart part, int hp, unsigned int bleed_rate, unsigned int hp_reproduction_rate);
	unsigned int getHP(Character::BodyPart bodypart) const;
	void setHP(Character::BodyPart bodypart, unsigned int hp);
	void damage(const CharacterPtr &character, Character::BodyPart bodypart, unsigned int dmg, const RoomPtr &room);
	void heal(const CharacterPtr &character, unsigned int hp);
	bool isAlive() const { return alive; }

	std::string getHealthReport(const Character *character, bool detailed = false) const;

	void registerDamageCallback(std::function<void(const CharacterPtr &, Character::BodyPart, unsigned int)> &&callback);
	void registerHealCallback(std::function<void(const CharacterPtr &, unsigned int)> &&callback);
	void registerDieCallback(std::function<void(CharacterPtr, const RoomPtr &)> &&callback);

private:
	class BodyPart
	{
	public:
		Character::BodyPart part;
		int hp;
		unsigned int bleed_rate;
		unsigned int hp_reproduction_rate;
		BodyPart(Character::BodyPart part, int hp, unsigned int bleed_rate, unsigned int hp_reproduction_rate) : part(part), hp(hp), bleed_rate(bleed_rate), hp_reproduction_rate(hp_reproduction_rate) {}
		int bleed(unsigned int tick) const { return (int)((((100-hp)*bleed_rate)/100)*tick); }
		void heal(unsigned int tick) { hp += (int)(hp_reproduction_rate*tick); }
	};
	std::vector<BodyPart> bodyparts;
	int blood_bank;

	bool alive;
	std::vector<std::function<void(const CharacterPtr &, Character::BodyPart, unsigned int)>> dmgCallbacks;
	std::vector<std::function<void(const CharacterPtr &, unsigned int)>> healCallbacks;
	std::vector<std::function<void(CharacterPtr, const RoomPtr &)>> dieCallbacks;
};
